package net.towee.client.com.stuff.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasOpenHandlers;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

import net.towee.client.com.stuff.presenter.GroupUsersShowerPresenter.Display;
import net.towee.client.i18n.ToweeConstants;
import net.towee.client.resources.ClientResource;
import net.towee.client.widgets.ListItemWidget;
import net.towee.client.widgets.UnorderedListWidget;
import net.towee.model.account.AccountGroup;
import net.towee.model.account.AccountIdentity;
import net.towee.model.account.Role;
import net.towee.model.account.impl.RoleImpl;
import net.towee.model.utils.Pair;

public class GroupUsersShowerView extends FlowPanel implements Display,
		HasValueChangeHandlers<Pair<AccountIdentity, Role>>, HasOpenHandlers<AccountIdentity> {
	private final ToweeConstants constants;
	private final ClientResource resource;

	private final List<Role> rolesList = new ArrayList<Role>();
	private final Button moreButton = new Button();
	private final FlowPanel moreButtonContainer = new FlowPanel();
	private boolean canChangeRoles = false;
	private boolean canKickUsers = false;
	
	private final Map<String, Widget> users = new HashMap<String, Widget>();

	@Inject
	public GroupUsersShowerView(ToweeConstants constants, ClientResource resource) {
		this.constants = constants;
		this.resource = resource;

		setStyleName(resource.css().stuffGroupUsers());

		moreButton.setStyleName(resource.css().moreSearchResultButton());
		moreButton.setText(constants.moreSearchResult());
		moreButtonContainer.add(moreButton);
		moreButtonContainer.getElement().getStyle().setProperty("clear", "left");
	}

	@Override
	public void showUser(final AccountIdentity idnt, AccountGroup group, boolean me) {
		final FlowPanel container = new FlowPanel();
		container.getElement().setAttribute("user", "");

		// Create roles list
		final ListBox roles = new ListBox();
		roles.getElement().setAttribute("roles", "");
		for (Role r : rolesList) {
			roles.addItem(r.getName(), r.getId());

			if (group.getRole().equals(r))
				roles.setSelectedIndex(roles.getItemCount() - 1);
		}

		if (!canChangeRoles)
			roles.setEnabled(false);

		// For changing role
		roles.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				int index = rolesList.indexOf(new RoleImpl(roles.getValue(roles.getSelectedIndex()),
						null, false));

				if (index >= 0)
					ValueChangeEvent.fire(GroupUsersShowerView.this, new Pair<AccountIdentity, Role>(
							idnt, rolesList.get(index)));
			}
		});

		UnorderedListWidget ul = new UnorderedListWidget();
		container.add(ul);
		
		// Create avatar
		ListItemWidget avatar = new ListItemWidget();
		avatar.getElement().setAttribute("avatar", "");
		ul.add(avatar);

		// Create identity
		ListItemWidget idcont = new ListItemWidget();
		idcont.getElement().setAttribute("id", "");
		Label name = new Label(idnt.getFullName());
		idcont.add(name);
		idcont.add(roles);

		// Kick button
		if (!me) {
			Button kick = new Button(constants.kickUser());
			kick.getElement().setAttribute("kick", "");
			idcont.add(kick);

			kick.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					OpenEvent.fire(GroupUsersShowerView.this, idnt);
					removeUser(idnt.getId());
				}
			});
		}
		
		ul.add(idcont);
		
		users.put(idnt.getId(), roles);

		moreButtonContainer.removeFromParent();
		add(container);
		add(moreButtonContainer);
	}
	
	@Override
	public void removeUser(String id) {
		if(users.containsKey(id)) {
			users.get(id).getParent().getParent().getParent().removeFromParent();
			users.remove(id);
		}
	}

	@Override
	public void setNumberOfUsers(int count) {
		// TODO Auto-generated method stub

	}

	@Override
	public void addRole(Role r) {
		rolesList.add(r);
	}

	@Override
	public void canChangeRoles() {
		this.canChangeRoles = true;
		
		for(Widget w : users.values()) {
			((ListBox)w).setEnabled(true);
		}
	}

	@Override
	public void canKickUser() {
		this.canKickUsers = true;
		this.getElement().setAttribute("canKickUsers", "");
	}

	@Override
	public void onUsersLoading() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onUsersLoaded() {
		// TODO Auto-generated method stub

	}

	@Override
	public void noUsers() {
	}

	@Override
	public void noMore() {
		moreButtonContainer.removeFromParent();
	}

	@Override
	public HasClickHandlers getMoreButton() {
		return moreButton;
	}

	@Override
	public HasValueChangeHandlers<Pair<AccountIdentity, Role>> getRoleChanger() {
		return this;
	}

	@Override
	public HasOpenHandlers<AccountIdentity> getKickUserHandlers() {
		return this;
	}

	@Override
	public HandlerRegistration addOpenHandler(OpenHandler<AccountIdentity> handler) {
		return addHandler(handler, OpenEvent.getType());
	}

	@Override
	public HandlerRegistration addValueChangeHandler(
			ValueChangeHandler<Pair<AccountIdentity, Role>> handler) {
		return addHandler(handler, ValueChangeEvent.getType());
	}
}
